home *** CD-ROM | disk | FTP | other *** search
- /*
- cop.cfm -- C Object Programming: object
- source template.
-
- (C) Copyright 1992 John W. Small
- All rights reserved
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, Virginia 22102 8072 USA
- Voice: (703) 759-3838
-
- Always edit a cloned copy of this file. With
- the case-sensitive flag set and word-only
- flag reset ...
-
- Find and Replace with something like
-
- structFileName foobar
- structType foobar
- structFncPrefix FB
-
- Edit the remaining text to fully declare your
- new object. This file is setup to suggest
- that your new object inherits three previously
- declared objects (base1, base2, and base3),
- the first of which has inherited two more
- objects. The third is a virtual base class.
- All the objects in the hierarchy supposedly
- have vFt's (Virtual Function Tables) that have
- one or more vF's overridden by the object being
- declared. Simply delete those items not
- pertaining to the new object you're declaring.
- You should find enough structure here to guide
- you in expanding this boiler plate for more
- complicated hierarchies if need be.
-
- Find and replace with something like
-
- base1FileName strawber
- base1StructType Strawberry
- base1StructFncPrefix SWB
-
- or delete those lines containing unnecessary
- items. Complete the find and replace process
- for base11, base12, base2, and base3 and delete
- any comments you find inappropriate such as
- this one.
- */
-
-
- /*
- structFileName.c -- COP object source
- */
-
-
- #include "structFileName.h"
-
-
- /*
- See cop.hfm notes on implicit
- type casting chains.
- */
- polyBaseThiS_0_def(structFncPrefix,
- base1StructType,structType)
- /* No semicolon needed! */
-
-
- /* Define structType's static data */
-
- static_def(structType);
-
-
-
- /* Define structType's default vFt for new vF's */
-
- vFt_def(structType,structType) = {
-
- vF_value(structFncPrefix,structFncPrefix,
- dummyVf),
- vF_value(structFncPrefix,structFncPrefix,
- destruct)
- /*
- vFts are assumed to be initialized to
- valid vFs, i.e. no checks are made by
- the vf_runTimeBind() macro!
- */
-
- };
-
-
- /*
- Define vf's for structType's default vFt.
-
- In practice you'll find it easy to copy the
- vf_decl()s from the header file and edit them
- to read vf_def().
- */
-
-
- vf_def(void,structFncPrefix,structFncPrefix,
- dummyVf,(structType * thiS, ...))
- {
- ???
- }
-
- vf_def(void,structFncPrefix,structFncPrefix,
- destruct,(structType * thiS, unsigned nobj,
- int malloced))
- {
- struct_destruct(structFncPrefix,thiS,nobj,
- malloced);
-
- /*
- When overriding this vf for a derived struct
- besure to call the derived struct's
- "struct_destruct". Remember "thiS" must be
- type cast to the overriding struct's thiS!
- That's because destruction begins at the last
- derived class and works back.
-
- struct_destuct(overridingStructFncPrefix,
- structFncPrefix_overridingStructTypeThiS
- (thiS),nobj,malloced);
- */
-
- }
-
-
-
- /*
- Define structType's overriding vFt's for all
- base structs within the inherited hierarchy
- having vf's overridden at StructName level.
- */
-
-
- /*
- It's easiest if you copy the complete vFt_def
- and edit as it reads below. That way non
- overridden vf's can be left unmodified and
- the tracking of overrides at various levels
- is thus not a problem.
- */
-
- vFt_def(structType,base1StructType) = {
-
- /* override a base1 vf */
-
- vF_value(structFncPrefix,
- base1StructFncPrefix,vfbase1);
-
- /*
- Perhaps not all vfs are overridden at this
- level but a vF must be specified for each
- entry in the table! In such cases assign the
- non overridden value to the table. Notice
- that only overridden vfs are defined below
- since the non overridden have already been
- defined elsewhere.
- */
-
- /* This vf is not overridden! */
-
- vF_value(base1StructFncPrefix,
- base1StructFncPrefix,???);
-
- };
-
-
- /*
- Again, copying vf_decl()s from the header and
- editing them to read vf_def()s saves a great
- deal of time here!
- */
-
- vf_def(base1StructType *,structFncPrefix,base1StructFncPrefix,
- vfbase1,(base1StructType * thiS, ...))
- {
- /*
- For overriding vfs remember to use the type
- cast macros for "thiS", i.e.
-
- structType * dThiS =
- base1StructFncPrefix_structTypeThiS(thiS);
-
- Then use "dThiS" to access data in the derived
- struct!
- */
- ???
- return thiS;
-
- /*
- If you need a virtual function to return a
- pointer to the current derived level code
- simply return dThiS instead:
-
- return (base1StructType *) dThiS;
-
-
- Be sure to typecast it back to (structType *)
- before using. (Note: this is not yet a C++
- feature.)
- */
-
- }
-
-
- vFt_def(structType,base11StructType) = {
-
- vF_value(structFncPrefix,
- base11StructFncPrefix,vfbase11);
-
- /*
- Here's an example of a base11 vf overridden at
- the base1 level but not at the current level.
- If you copied the complete vFt_def() from
- base1 and edited the overridden vf's at the
- structType level, it requires no thought as
- to what might have been overridden at
- intermediate levels. If you go back and edit
- the intermediate level overrides then your
- maintenance task is going to require some
- work. Hay, what can I say? - this isn't C++!
- */
-
- vF_value(base1StructType,
- base11StructFncPrefix,???);
-
- };
-
- vf_def(void,structFncPrefix,base11StructFncPrefix,
- vfbase11,(base11StructType * thiS, ...))
- {
- ???
- }
-
-
- vFt_def(structType,base12StructType) = {
- vF_value(structFncPrefix,
- base12StructType,vfbase12);
- vF_value(base12StructType,
- base12StructType,???);
- };
-
- vf_def(int,structFncPrefix,base12StructFncPrefix,
- vfbase12,(base12StructType * thiS, ...))
- {
- ???
- return ???;
- }
-
-
- vFt_def(structType,base2StructType) = {
- vF_value(structFncPrefix,
- base2StructFncPrefix,vfbase2);
- vF_value(base2StructFncPrefix,
- base2StructFncPrefix,???);
- };
-
- vf_def(int,structFncPrefix,base2StructFncPrefix,
- vfbase2,(base2StructType * thiS, ...))
- {
- ???
- return ???;
- }
-
- vFt_def(structType,base3StructType) = {
- vF_value(structFncPrefix,
- base3StructFncPrefix,vfbase3);
- };
-
- vf_def(int,structFncPrefix,base3StructFncPrefix,
- vfbase3,(base3StructType * thiS, ...))
- {
- ???
- return ???;
- }
-
-
- /*
- Define structType's protected constructors
- and destructors. Be sure to follow this
- format even for simple objects to insure that
- they are extensible -- you'll begin to see the
- reasoning once your hierarchies begin to grow.
- */
-
- struct_initVFTs_def(structFncPrefix,
- (structType * thiS,
- void * descendanT_0
- , vFT_0_decl(structType)
- /*
- All base structs with vFTs need to be
- initialized thus require their specific formal
- parameter. A null pointer when passed as a
- actual parameter indicates to use the default
- vFT in question.
- */
- , vFT_0_decl(base1StructType)
- , vFT_0_decl(base11StructType)
- , vFT_0_decl(base12StructType)
- , vFT_0_decl(base2StructType)
- , vbThiS_decl(base3StructType)
- , vbDescendanT_0_decl(base3StructType)
- , vFT_0_decl(base3StructType)
- ))
- /* Be sure to have enough closing parentheses above! */
- {
-
- /*
- Polymorphic structs must call poly_assign!
- */
- poly_assign(thiS,descendanT_0);
-
- /*
- Assign vFT at this level if appropriate.
- */
- vFT_assign(structType,structType,
- thiS,vFT_0_name(structType));
-
- /*
- Call only directly inherited base struct
- struct_initVFTs() macros! Notice that the
- "thiS" pointers are type cast to their
- respective base struct pointers and that the
- descendanT_0 pointers are set in the base
- structs to point to the current level struct!
- When each struct in a hierarchy follows this
- convention, the necessary chaining is
- automatically established for the type cast
- macros converting from base to derived
- structs. These are the type casts necessary
- within overriding virtual functions!
- */
- struct_initVFTs(base1StructFncPrefix,
- (structFncPrefix_base1StructTypeThiS
- (thiS), (void *) thiS
- , vFT_0_name(base1StructType)
- , vFT_0_name(base11StructType)
- , vFT_0_name(base12StructType)
- ));
- /* Be sure to have enough closing parentheses above! */
- struct_initVFTs(base2StructFncPrefix,
- (structFncPrefix_base2StructTypeThiS
- (thiS), (void *) thiS
- , vFT_0_name(base2StructType)
- ));
- /* Be sure to have enough closing parentheses above! */
-
- /*
- If base2 branch of the hierarchy hadn't been
- polymorphic the call above would have been:
-
- struct_initVFTs(base2StructFncPrefix,NO_VFTs);
- */
-
- /*
- Remember base3 has no way to know that it's
- a virtual base structure. Notice that the
- virtual base's descendanT pointer points to
- either is directly derived node or preferribly
- to the virtual base host structure at the
- corresponding casing structure joint.
- */
- struct_initVFTs(base3StructFncPrefix,
- ( vbThiS_name(base3StructType)
- , vbDescendant_value(base3StructType,
- thiS)
- , vFT_0_name(base3StructType)
- ));
- /* Be sure to have enough closing parentheses above! */
-
- }
-
- /*
- The following protected constructor is called
- with nobj == 1 by derived structure
- constructors or with nobj >= 1 to instanciate
- an instance or vector of instances of the
- current level structure.
- */
-
-
- struct_init_def(structType,structFncPrefix,_,
- (structType * thiS_0
- , unsigned nobj
- , vbThiS_decl(base3StructType)
- , ... initializers
- ))
- {
- unsigned i, fail;
- int malloced = 0;
-
- if (!nobj)
- return (structType *)0;
- if (!thiS_0) if ((thiS_0 = (structType *)
- structFncPrefix_malloc(nobj))
- == (structType *)0)
- return (structType *)0;
- else
- malloced = 1;
- for (i = fail = 0; i < nobj; i++) {
-
-
- /*
- Initialize all base structs first,
- then initialize vFTs, etc.,
- then initialize structType data.
- */
-
- if (!struct_init(base1StructFncPrefix,
- base1StructFncOvrLdSuffix,
- (structFncPrefix_base1StructTypeThiS(&thiS_0[i])
- ,1, ... initializers))) {
- fail = 1;
- break;
- }
- if (!struct_init(base2StructFncPrefix,
- base2StructFncOvrLdSuffix,
- (structFncPrefix_base2StructTypeThiS(&thiS_0[i])
- ,1, ... initializers))) {
- /* leave all bases at this index destructed */
- struct_destruct(base1StructFncPrefix,
- structFncPrefix_base1StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- fail = 1;
- break;
- }
- if (!struct_init(base3StructFncPrefix,
- base3StructFncOvrLdSuffix,
- (structFncPrefix_base3StructTypeThiS(&thiS_0[i])
- ,1, vbThiS_name(base3StructType)
- , ... initializers))) {
- /* leave all bases at this index destructed */
- struct_destruct(base2StructFncPrefix,
- structFncPrefix_base2StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- struct_destruct(base1StructFncPrefix,
- structFncPrefix_base1StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- fail = 1;
- break;
- }
-
-
- /* setup default vFT for structType level */
-
- struct_initVFTs(structFncPrefix
- ,(&thiS_0[i], (void *)0
- , vFT0(structType)
- , vFT0(base1StructType)
- /* or vFT_value(structType,base1StructType) */
- , vFT0(base11StructType)
- /* or vFT_value(structType,base11StructType) */
- , vFT0(base12StructType)
- /* or vFT_value(structType,base12StructType) */
- , vFT0(base2StructType)
- /* or vFT_value(structType,base2StructType) */
- , vbThiS_name(base3StructType)
- , vbDescendanT_value(base3StructType,thiS)
- , vFT0(base3StructType)
- /* or vFT_value(structType,base3StructType) */
- ));
- /* Be sure to have enough closing parentheses above! */
-
- /* initialize structType data level */
-
- thiS_0[i].??? = ???;
- if (current level initialization fails) {
- /* destruct all data at this level and index */
- ???
- /* destruct all bases at this index */
- struct_destruct(base3StructFncPrefix,
- structFncPrefix_base3StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- struct_destruct(base2StructFncPrefix,
- structFncPrefix_base2StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- struct_destruct(base1StructFncPrefix,
- structFncPrefix_base1StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- fail = 1;
- break;
- }
-
- } /* for */
-
- if (fail) {
- /*
- All indices >= "i" have already been destructed
- as required. Indices i-1 to 0 are now
- destructed via the destructor since we're
- inside the constructor of the instance level if
- i > 0. Remember that if this is an
- intermediate constructor call that i == 0
- and malloced == 0 always so no further
- processing is required at this level and NULL
- is returned to the calling level constructor.
- */
- if (i)
- struct_destruct(structFncPrefix,thiS_0,i,malloced);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- else if (malloced)
- structFncPrefix_free(thiS_0);
- return (structType *) 0;
- }
-
- return thiS_0;
- }
-
- /*
- If you have more than one constructor then
- repeat the struct_init_def() definition above
- with an overloaded suffix parameter and the
- appropriate initialization parameters.
- */
-
-
-
- /*
- This protected destructor is called by the
- public destructor macro. It is also called
- by the protected struct_init constructor in
- the event of a failure to construct. Thus
- this destructor must be able to correctly
- handle any partially constructed data that
- may be handed off by the failing constructor!
- */
-
- struct_destruct_def(structType,structFncPrefix)
- {
- unsigned i;
-
- if (!thiS_0 || !nobj)
- return;
-
- for (i = nobj; i--; /* no reinit */) {
-
- /*
- Setup vFT and polymorphic virtual base
- descendants for structType level.
-
- The vFT must be initialized exactly the same
- way they were in struct_init_def() above!
- */
- struct_initVFTs(structFncPrefix
- ,(&thiS_0[i], (void *)0
- , vFT0(structType)
- , vFT0(base1StructType)
- /* or vFT_value(structType,base1StructType) */
- , vFT0(base11StructType)
- /* or vFT_value(structType,base11StructType) */
- , vFT0(base12StructType)
- /* or vFT_value(structType,base12StructType) */
- , vFT0(base2StructType)
- /* or vFT_value(structType,base2StructType) */
- , vbThiS_name(base3StructType)
- , vbDescendanT_value(base3StructType,thiS)
- , vFT0(base3StructType)
- /* or vFT_value(structType,base3StructType) */
- ));
- /* Be sure to have enough closing parentheses above! */
-
-
- /*
- Destruct structType data here. Beware of
- partially constructed data handed off by a
- failing constructor! This should never be
- the case if you follow the form above in
- struct_init_def() exactly.
- */
-
- thiS_0[i].???
-
-
- /* destruct base struct data */
-
- struct_destruct(base3FncPrefix,
- structFncPrefix_base3StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- struct_destruct(base2FncPrefix,
- structFncPrefix_base2StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
- struct_destruct(base1FncPrefix,
- structFncPrefix_base1StructTypeThiS
- (&thiS_0[i]),1,0);
- /*
- Remember struct_destruct() DOESN'T take a
- parenthesized actualParams argument!
- */
-
-
- } /* for */
-
- if (malloced)
- structFncPrefix_free(thiS_0);
- }
-
-
- /*
- Define structType member functions below
- following their declaration order laid out
- in the header file.
- */
-